﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using Mbs.Collections;
using Mbs.Configuration;
using Mbs.Elements;

namespace Mbs.Modularity.AddIns
{ 
    [Serializable]
    [DebuggerDisplay("Path={Path},Label={Label},Command={Command}, Type={Type},AddInName={AddInName}")]
    public class AddInItem : IAddInItem
    {
        public string AddInName { get; internal set; }
        public string Id { get; private set; }
        public string Label { get { return Properties.Get<string>("Label"); } }
        public string Type { get; private set; }
        public string Command { get; private set; }
        public string Path { get; private set; }
        public string ParentPath { get; private set; }

        public IAddInItemCollection Items { get; private set; }
        public INode[] Extensions { get; private set; }

        protected AddInItem() { }

        public AddInItem(string addinName, string  parentPath, IPropertySet properties, params INode[] extensionNodes)
        {
            this.AddInName = addinName;
            this.ParentPath = parentPath;
            this.Properties = properties;
            Extensions = extensionNodes == null ? new INode[0] : extensionNodes;

            this.Id = properties.Get<string>("Id");
            //this.Label = properties.Get<string>("Label");
            this.Type = properties.Get<string>("Type"); 
            this.Command = properties.Get<string>("Command");

            Items = new AddInItemCollection();
            if (!string.IsNullOrEmpty(ParentPath))
                Path = ParentPath.Trim('/') + "/" + Id;
            else
                Path = Id;//root path


        }

        public IAddInNode Clone()
        {
            var o = new AddInItem();
            o.Properties = Properties;
            o.AddInName = AddInName;
            o.Id = Id;
            //o.Label = Label;
            o.Type = Type;
            o.Command = Command;
            o.Path = Path;
            o.ParentPath = ParentPath;

            o.Items = Items.Clone();
            o.Extensions = new INode[Extensions.Length];
            if (o.Extensions.Length > 0)
                Extensions.CopyTo(o.Extensions, 0);
          
            return o;
        }

        object ICloneable.Clone()
        {
            return Clone();
        }


        
        public IPropertySet Properties { get; private set; }
      


        public object Build(object owner)
        {
            return BuildItem(owner, new List<object>());
        }

        private object BuildItem(object owner, List<object> subItems)
        {
            var o = ServiceLocator.Current.Get(Path);


            var builder = ServiceLocator.Current.Get<IElementBuilder>(Type);
            if (builder == null)
                throw new AddInLoadException("system no register ElementBuilder.");

            if (subItems == null)
                subItems = new List<object>();

            if (o == null)
            {
                o = builder.Create(owner, this);
                if (o == null) return null;

                var registry = ServiceRegistry.Current;
                if (registry != null)
                    registry.RegisterInstance(Path, o);
            }

            if (o == null)
                return null;

            if (Items.Count > 0)
                foreach (var item in Items)
                    subItems.Add((item as AddInItem).BuildItem(owner, null));

            builder.InitInstance(owner, this, subItems, o);

            return o;
        }

        public override string ToString()
        {
            return String.Format("AddItem: path[{0}], label[{1}], command[{2}], type[{3}], addinName[{4}]", Path, Label, Command, Type, AddInName);
        }
    }
}